﻿using System;
using System.Data;

namespace Core
{
    public class DateTimeUtil
    {
        #region "DateTime Constant"

        /// <summary>
        /// Define cultureinfo en-US
        /// </summary>
        public static IFormatProvider US_FORMAT = new System.Globalization.CultureInfo("en-US", true);
        /// <summary>
        /// Define cultureinfo th-TH
        /// </summary>
        public static IFormatProvider TH_FORMAT = new System.Globalization.CultureInfo("th-TH", true);
        /// <summary>
        /// Define Date Format dd/MM/yyyy
        /// </summary>
        public static string DATE_FORMAT = "dd/MM/yyyy";
        /// <summary>
        /// Define DateTime Format dd/MM/yyyy HH:mm:ss
        /// </summary>
        public static string DATETIME_FORMAT = "dd/MM/yyyy HH:mm:ss";
        /// <summary>
        /// Define Time Format HH:mm
        /// </summary>
        public static string TIME_FORMAT = "HH:mm";
        /// <summary>
        /// Define month list name in thai language
        /// </summary>
        public static string[,] MONTH_LIST_NAME = { { "1", "มกราคม" }, { "2", "กุมภาพันธ์" }, { "3", "มีนาคม" }, { "4", "เมษายน" }, { "5", "พฤษภาคม" }, { "6", "มิถุนายน" }, { "7", "กรกฎาคม" }, { "8", "สิงหาคม" }, { "9", "กันยายน" }, { "10", "ตุลาคม" }, { "11", "พฤศจิกายน" }, { "12", "ธันวาคม" } };

        #endregion

        /// <summary>
        /// Determines whether [is date between] [the specified start].
        /// </summary>
        /// <param name="start">The start.</param>
        /// <param name="end">The end.</param>
        /// <param name="date">The date.</param>
        /// <returns>
        /// 	<c>true</c> if [is date between] [the specified start]; otherwise, <c>false</c>.
        /// </returns>
        public static bool IsDateBetween(DateTime start, DateTime end, DateTime date)
        {
            if (date >= start && date <= end)
            {
                return true;
            }

            return false;
        }

        /// <summary>
        /// Gets the name of the month.
        /// </summary>
        /// <param name="monthNum">The month num.</param>
        /// <returns></returns>
        public static string GetMonthName(int monthNum)
        {
            return GetMonthName(monthNum, false);
        }

        /// <summary>
        /// Gets the name of the month.
        /// </summary>
        /// <param name="monthNum">The month num.</param>
        /// <param name="abbreviate">if set to <c>true</c> [abbreviate].</param>
        /// <returns></returns>
        public static string GetMonthName(int monthNum, bool abbreviate)
        {
            if (monthNum < 1 || monthNum > 12)
                throw new ArgumentOutOfRangeException("monthNum");
            DateTime date = new DateTime(1, monthNum, 1);
            if (abbreviate)
                return date.ToString("MMM");
            return date.ToString("MMMM");
        }

        /// <summary>
        /// Gets the month number.
        /// </summary>
        /// <param name="monthName">Name of the month.</param>
        /// <param name="abbreviate">if set to <c>true</c> [abbreviate].</param>
        /// <returns></returns>
        public static int GetMonthNumber(string monthName, bool abbreviate)
        {
            if (abbreviate)
            {
                return DateTime.ParseExact(monthName, "MMM", System.Globalization.CultureInfo.CurrentCulture).Month;
            }
            return DateTime.ParseExact(monthName, "MMMM", System.Globalization.CultureInfo.CurrentCulture).Month;
        }

        /// <summary>
        /// Gets the month value from string.
        /// </summary>
        /// <param name="date">The date.</param>
        /// <returns></returns>
        public static int GetMonthValueFromString(string date)
        {
            int month = 0;

            if (!string.IsNullOrEmpty(date))
            {
                month = Convert.ToInt32(date.Substring(3, 2));
            }

            return month;
        }

        /// <summary>
        /// Gets the year value from string.
        /// </summary>
        /// <param name="date">The date.</param>
        /// <returns></returns>
        public static int GetYearValueFromString(string date)
        {
            int year = 0;
            if (!string.IsNullOrEmpty(date))
            {
                year = Convert.ToInt32(date.Substring(6, 4));
            }

            return year;
        }

        /// <summary>
        /// Gets the date time from string.
        /// </summary>
        /// <param name="dateTime">The date time.</param>
        /// <returns></returns>
        public static DateTime GetDateTimeFromString(string dateTime)
        {
            string date = dateTime.Split(' ')[0];
            string time = dateTime.Split(' ')[1];

            int day = Convert.ToInt32(date.Substring(0, 2));
            int month = Convert.ToInt32(date.Substring(3, 2));
            int year = Convert.ToInt32(date.Substring(6, 4));

            int hour = Convert.ToInt32(time.Substring(0, 2));
            int minute = Convert.ToInt32(time.Substring(3, 2));
            int second = Convert.ToInt32(time.Substring(6, 2));

            return new DateTime(year, month, day, hour, minute, second);
        }

        /// <summary>
        /// Gets the date time from string.
        /// </summary>
        /// <param name="date">The date.</param>
        /// <param name="time">The time.</param>
        /// <returns></returns>
        public static DateTime GetDateTimeFromString(string date, string time)
        {
            int day = Convert.ToInt32(date.Substring(0, 2));
            int month = Convert.ToInt32(date.Substring(3, 2));
            int year = Convert.ToInt32(date.Substring(6, 4));

            int hour = Convert.ToInt32(time.Substring(0, 2));
            int minute = Convert.ToInt32(time.Substring(3, 2));
            const int second = 0;

            return new DateTime(year, month, day, hour, minute, second);
        }

        /// <summary>
        /// Gets the date time nullable from string.
        /// </summary>
        /// <param name="date">The date.</param>
        /// <param name="time">The time.</param>
        /// <returns></returns>
        public static DateTime? GetDateTimeNullableFromString(string date, string time)
        {
            if (date != string.Empty)
            {
                int day = Convert.ToInt32(date.Substring(0, 2));
                int month = Convert.ToInt32(date.Substring(3, 2));
                int year = Convert.ToInt32(date.Substring(6, 4));

                int hour = Convert.ToInt32(time.Substring(0, 2));
                int minute = Convert.ToInt32(time.Substring(3, 2));
                const int second = 0;

                return new DateTime(year, month, day, hour, minute, second);
            }
            return null;
        }

        /// <summary>
        /// Gets the date from string.
        /// </summary>
        /// <param name="date">The date.</param>
        /// <returns></returns>
        public static DateTime GetDateFromString(string date)
        {
            if (date != string.Empty)
            {
                int day = Convert.ToInt32(date.Substring(0, 2));
                int month = Convert.ToInt32(date.Substring(3, 2));
                int year = Convert.ToInt32(date.Substring(6, 4));

                return new DateTime(year, month, day);
            }
            return DateTime.MinValue;
        }

        /// <summary>
        /// Gets the date nullable from string.
        /// </summary>
        /// <param name="date">The date.</param>
        /// <returns></returns>
        public static DateTime? GetDateNullableFromString(string date)
        {
            if (date != string.Empty)
            {
                int day = Convert.ToInt32(date.Substring(0, 2));
                int month = Convert.ToInt32(date.Substring(3, 2));
                int year = Convert.ToInt32(date.Substring(6, 4));

                return new DateTime(year, month, day);
            }
            return null;
        }

        /// <summary>
        /// Gets the time string date.
        /// </summary>
        /// <param name="date">The date.</param>
        /// <returns></returns>
        public static string GetTimeStringDate(DateTime? date)
        {
            return date.HasValue ? ((DateTime)date).ToString(TIME_FORMAT) : "00:00";
        }

        /// <summary>
        /// Gets the time from string.
        /// </summary>
        /// <param name="time">The time.</param>
        /// <returns></returns>
        public static DateTime GetTimeFromString(string time)
        {
            DateTime dtNow = DateTime.Now;

            int hour = Convert.ToInt32(time.Substring(0, 2));
            int minute = Convert.ToInt32(time.Substring(3, 2));
            const int second = 0;

            return new DateTime(dtNow.Year, dtNow.Month, dtNow.Day, hour, minute, second);
        }

        /// <summary>
        /// Gets the date from string.
        /// </summary>
        /// <param name="date">The date.</param>
        /// <param name="isBuddhistEra">if set to <c>true</c> [is buddhist era].</param>
        /// <returns></returns>
        public static DateTime GetDateFromString(string date, bool isBuddhistEra)
        {
            int day = Convert.ToInt32(date.Substring(0, 2));
            int month = Convert.ToInt32(date.Substring(3, 2));
            int year = Convert.ToInt32(date.Substring(6, 4));

            if (isBuddhistEra)
            {
                return new DateTime(year - 543, month, day);
            }
            return new DateTime(year, month, day);
        }

        /// <summary>
        /// Gets the begin period.
        /// </summary>
        /// <param name="year">The year.</param>
        /// <param name="month">The month.</param>
        /// <returns></returns>
        public static DateTime GetBeginPeriod(int year, int month)
        {

            DateTime dtBeginPeriod = new DateTime(year, month, 1);

            return dtBeginPeriod;
        }

        /// <summary>
        /// Gets the end period.
        /// </summary>
        /// <param name="year">The year.</param>
        /// <param name="month">The month.</param>
        /// <returns></returns>
        public static DateTime GetEndPeriod(int year, int month)
        {
            DateTime dtS, dtE;

            if (month < 12)
            {
                dtS = new DateTime(year, month, 1);
                dtE = new DateTime(year, month + 1, 1);
            }
            else
            {
                dtS = new DateTime(year, 12, 1);
                dtE = new DateTime(year + 1, 1, 1);
            }

            TimeSpan ts = new TimeSpan(dtE.Subtract(dtS).Ticks);

            DateTime dtEndPeriod = new DateTime(year, month, ts.Days);

            return dtEndPeriod;
        }

        /// <summary>
        /// Gets the days in month.
        /// </summary>
        /// <param name="year">The year.</param>
        /// <param name="month">The month.</param>
        /// <returns></returns>
        public static int GetDaysInMonth(int year, int month)
        {
            DateTime dtS, dtE;

            if (month < 12)
            {
                dtS = new DateTime(year, month, 1);
                dtE = new DateTime(year, month + 1, 1);
            }
            else
            {
                dtS = new DateTime(year, 12, 1);
                dtE = new DateTime(year + 1, 1, 1);
            }

            TimeSpan ts = new TimeSpan(dtE.Subtract(dtS).Ticks);
            return ts.Days;
        }

        /// <summary>
        /// Gets the string from date.
        /// </summary>
        /// <param name="row">The row.</param>
        /// <param name="columnName">Name of the column.</param>
        /// <returns></returns>
        public static string GetStringFromDate(DataRow row, string columnName)
        {
            string returnMessage = "";
            if (!Convert.IsDBNull(row[columnName]))
            {
                DateTime date = Convert.ToDateTime(row[columnName]);
                returnMessage = date.ToString(DATE_FORMAT, US_FORMAT);

                returnMessage = returnMessage.Replace("-", "/");
            }

            return returnMessage;
        }

        /// <summary>
        /// Gets the string from date.
        /// </summary>
        /// <param name="date">The date.</param>
        /// <returns></returns>
        public static string GetStringFromDate(DateTime? date)
        {
            string returnMessage = date.HasValue ? ((DateTime)date).ToString(DATE_FORMAT, US_FORMAT) : "";

            return returnMessage.Replace("-", "/");
        }

        /// <summary>
        /// Gets the string long from date.
        /// </summary>
        /// <param name="date">The date.</param>
        /// <returns></returns>
        public static string GetStringLongFromDate(DateTime date)
        {
            string returnMessage = date.ToString(DATETIME_FORMAT, US_FORMAT);

            return returnMessage.Replace("-", "/");
        }

        /// <summary>
        /// Gets the milli seconds from minutes.
        /// </summary>
        /// <param name="minutes">The minutes.</param>
        /// <returns></returns>
        public static int GetMilliSecondsFromMinutes(int minutes)
        {
            return (minutes * 60 * 1000);
        }

        /// <summary>
        /// Gets the date time string from date.
        /// </summary>
        /// <param name="date">The date.</param>
        /// <returns></returns>
        public static string GetDateTimeStringFromDate(DateTime date)
        {
            return date.ToString("dd/MM/yyyy HH:mm:ss");
        }

        /// <summary>
        /// Gets the date time string from date.
        /// </summary>
        /// <param name="date">The date.</param>
        /// <returns></returns>
        public static string GetDateTimeStringFromDate(DateTime? date)
        {
            if (date.HasValue)
            {
                return ((DateTime)date).ToString("dd/MM/yyyy HH:mm:ss");
            }
            return "";
        }

        /// <summary>
        /// Converts the date string format.
        /// </summary>
        /// <param name="date">The date.</param>
        /// <returns></returns>
        public static string ConvertDateStringFormat(string date)
        {
            string[] arr = date.Split('/');
            return arr[1] + "/" + arr[0] + "/" + arr[2];
        }

        /// <summary>
        /// Converts to date time.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        public static DateTime? ConvertToDateTime(string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return null;
            }
            return Convert.ToDateTime(value);
        }

        /// <summary>
        /// Determines whether [is date valid] [the specified date value].
        /// </summary>
        /// <param name="dateValue">The date value.</param>
        /// <returns>
        ///   <c>true</c> if [is date valid] [the specified date value]; otherwise, <c>false</c>.
        /// </returns>
        public static bool IsDateValid(string dateValue)
        {
            DateTime d;
            return DateTime.TryParse(dateValue, out d);
        }
    }
}
